回想上篇文章,this 在執行的時候會 reference 呼叫該函式的物件;
今天份的學習則是,物件產生時也會一併出現的 --- prototype。
Prototype 又稱呼「原型」,當生成一個物件,則該物件一定會有一個 prototype 連結到另外一個物件,另外一個物件又會有 prototype 連結到另外一個物件,這一連串的連結稱作 prototype chain 「原型鍊」。
為什麼要有 prototype?
假設今天有個 物件-B 連到 物件-A,那麼 物件-B 可以享有 物件-A 的 properties/methods。
這個過程稱作 delegation。
var homework = {
topic: "JS"
};
// the homework default prototype linkage connects to
// the Object.prototype object
homework.toString();
// homework.toString() works even though
// homework doesn't have a toString() method,
// the delegation invokes Object.prototype.toString() instead
有一種方法,可以實作 Object Linkage,用 Object.create()
的方法,來創造鏈結
Object.create(null) creates an object that is not prototype linked anywhere, so it's purely just a standalone object
var homework = {
topic: "Math"
};
var otherHomework = Object.create(homework);
otherHomework.topic; // "Math"
Object.create()
方法,利用參數 homework 生成一個新的物件,並鏈結到 homework,再回傳這個新生成的物件。
homework.topic; // "Math"
otherHomework.topic; // "Math"
otherHomework.topic = "JS";
otherHomework.topic; // "JS"
homework.topic; // "Math"
otherHomework.topic = "JS";
這段 assignment 並不影響 homework 的 topic property,這個在同一個 prototype chain 擁有不同 property value 稱作 "shadowed property"。
The topic on otherHomework is "shadowing" the property of the same name on the homework object in the chain.
this
!!!this 會在函式執行的時候,reference 到呼叫該函式的物件;
var homework = {
study() {
console.log(`Please study ${ topic }`);
}
}
var mathHomework = Object.create(homework);
mathHomework.topic = "Math";
mathHomework.study(); // Please study Math
var jsHomework = Object.create(homework);
jsHomework.topic = "JS";
jsHomework.study(); // Please study JS
雖然 mathHomework 和 jsHomework 都鏈結到 homework,但是這兩個物件的 this 則是各自 reference 到 mathHomework 和 jsHomework,因為 this 只會被「誰呼叫」函式所影響。
[ 參考 ]
[ 圖片來源 ]